package com.yunhe.authority.repository.authority;

import com.yunhe.authority.domain.authority.Menu;
import com.yunhe.authority.domain.authority.Organization;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author zhengbo
 * @date 2021/2/24 10:20
 */
@Repository
public interface OrganizationRepository extends Neo4jRepository<Organization, Long> {

    @Query("match(o:Organization) where o.title={title} return o limit 1")
    Organization findByTitle(@Param("title") String title);

    @Query("match(o:Organization) where o.name={name} return o limit 1")
    Organization findByName(@Param("name") String name);

    /**
     * 根据项目ID和组织title获得组织
     * @param stationId 项目代码
     * @param title m名称
     * @return Organization
     */
    @Query("match (s:Station)-[:HAS_ORGANIZATION{stationId:{stationId}}]->(o:Organization) where o.title={title} return o limit 1")
    Organization findOrganizationByStationIdAndTitle(@Param("stationId") Long stationId, @Param("title") String title);

    /*******************************************************父子*******************************************************/

    /**
     * 删除父子组织关系
     * @param childId 子组织ID
     */
    @Query("start child=node({childId}) match ()-[r:HAS_CHILD]->(child) delete r")
    void delChildRelation(@Param("childId") Long childId);

    /**
     * 添加父子菜单关系
     * @param parentId 父菜单ID
     * @param childId 子菜单ID
     */
    @Query("start parent=node({parentId}),child=node({childId}) create (parent)-[:HAS_CHILD]->(child)")
    void addChildRelation(@Param("parentId") Long parentId, @Param("childId") Long childId);

    /**
     * 根据ID获得子列表
     * @param organizationId 组织ID
     */
    @Query("match (o:Organization)-[:HAS_CHILD]->(n) where ID(o)={organizationId} return n")
    Iterable<Organization> findChildren(@Param("organizationId") Long organizationId);

    /*******************************************************项目*******************************************************/

    /**
     * 根据项目ID获得绑定的所有组织列表
     * @param stationId 项目代码
     */
    @Query("match (s:Station)-[:HAS_ORGANIZATION{stationId:{stationId}}]->(o:Organization) return o")
    Iterable<Organization> findOrganizationByStationId(@Param("stationId") Long stationId);
    @Query("match (s:Station)-[:HAS_ORGANIZATION{stationId:{stationId}}]->(o:Organization)-[:HAS_CHILD*0..9]->(o1) return o1")
    Iterable<Organization> findOrgByStationId(@Param("stationId") Long stationId);

    /**
     * 添加组织与项目绑定关系
     * @param id 组织ID
     * @param stationId 项目ID
     */
    @Query("start station=node({stationId}),organization=node({id}) create (station)-[r:HAS_ORGANIZATION{stationId:{stationId}}]->(organization)")
    void organizationBindStation(@Param("id") Long id, @Param("stationId") Long stationId);

    /**
     * 删除组织与项目的关系（解绑）
     * @param stationId 项目ID
     */
    @Query("match (s:Station)-[r:HAS_ORGANIZATION{stationId:{stationId}}]->(o:organization) delete r")
    void organizationUnbindByStation(@Param("stationId") Long stationId);

    /*******************************************************单位*******************************************************/

    /**
     * 根据单位ID获得绑定的所有组织列表
     * @param firmId 单位代码
     */
    @Query("match (f:firm)-[:HAS_ORGANIZATION{firmId:{firmId}}]->(o:Organization) return o")
    Iterable<Organization> findOrganizationByFirmId(@Param("firmId") Long firmId);
    @Query("match (f:firm)-[:HAS_ORGANIZATION{firmId:{firmId}}]->(o:Organization)-[:HAS_CHILD*0..9]->(o1) return o1")
    Iterable<Organization> findOrgByFirmId(@Param("firmId") Long firmId);


    /**
     * 添加组织与单位绑定关系
     * @param id 组织ID
     * @param firmId 单位ID
     */
    @Query("start firm=node({firmId}),organization=node({id}) create (firm)-[r:HAS_ORGANIZATION{firmId:{firmId}}]->(organization)")
    void organizationBindFirm(@Param("id") Long id, @Param("firmId") Long firmId);

    /**
     * 删除组织与单位的关系（解绑）
     * @param firmId 单位ID
     */
    @Query("match (f:firm)-[r:HAS_ORGANIZATION{firmId:{firmId}}]->(o:organization) delete r")
    void organizationUnbindFirm(@Param("firmId") Long firmId);
    /**
     * 查询用户项目的协同组织
     * @param userId
     * @param stationId
     * @return
     */
    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{stationId:{stationId}}]->(o:Organization) where ID(u)={userId} return o")
    Iterable<Organization> findByUserIdAndStationId(@Param("userId") Long userId,@Param("stationId")  Long stationId);

    /**
     * 查询用户单位的协同组织
     * @param userId
     * @param firmId
     * @return
     */
    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{firmId:{firmId}}]->(o:Organization) where ID(u)={userId} return o")
    Iterable<Organization> findByUserIdAndFirmId(@Param("userId")  Long userId, @Param("firmId")  Long firmId);

    @Query("MATCH(u:User)-[:HAS_ORG{stationId:{stationId}}]->(o:Organization) where ID(u)={userId} return o")
    Iterable<Organization> findBelongOrgByUserIdAndStationId(@Param("userId") Long userId,@Param("stationId")  Long stationId);

    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{firmId:{firmId}}]->(o:Organization) where ID(u)={userId} return o")
    Iterable<Organization> findBelongOrgByUserIdAndFirmId(@Param("userId")  Long userId, @Param("firmId")  Long firmId);

    @Query("MATCH(u:User)-[:HAS_ORG{stationId:{stationId}}]->(o:Organization{function:{orgFunction}}) where ID(u)={userId} return o")
    Iterable<Organization> findBelongOrgByUserIdAndStationId(@Param("userId") Long id,@Param("stationId") Long stationId,@Param("orgFunction") String orgFunction);

    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{stationId:{stationId}}]->(o:Organization{function:{orgFunction}}) where ID(u)={userId} return o")
    Iterable<Organization> findSynergyOrgByUserIdAndStationId(@Param("userId") Long id,@Param("stationId") Long stationId,@Param("orgFunction") String orgFunction);

    @Query("MATCH(u:User)-[:HAS_ORG{stationId:{stationId}}]->(o:Organization{function:{orgFunction}})-[:HAS_CHILD]->(s) return s")
    Iterable<Organization> findBelongChildOrgByUserId(@Param("userId") Long id,@Param("stationId") Long stationId,@Param("orgFunction") String orgFunction);

    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{stationId:{stationId}}]->(o:Organization{function:{orgFunction}})-[:HAS_CHILD]->(s) return s")
    Iterable<Organization> findSynergyChildOrgByUserId(@Param("userId") Long id,@Param("stationId") Long stationId,@Param("orgFunction") String orgFunction);

    @Query("MATCH(o:Organization)-[:HAS_CHILD*0..9]->(s) where ID(o)={orgId} return s")
    Iterable<Organization> findSubOrgByOrgId(@Param("orgId") Long orgId);

    @Query("match (s:Station)-[:HAS_ORGANIZATION{stationId:{stationId}}]->(o:Organization)-[:HAS_CHILD*0..9]->(o1) where ID(o) = {orgId} return o1")
    Iterable<Organization> findChildOrg(@Param("orgId") Long orgId,@Param("stationId") Long stationId);

    @Query("match (s:Station)-[:HAS_ORGANIZATION{stationId:{stationId}}]->(o:Organization{function:{orgFunction}})-[:HAS_CHILD*0..9]->(o1) return o1")
    List<Organization> findOrgByStationIdAndorgFunction(@Param("orgFunction") String orgFunction, @Param("stationId") Long stationId);

    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{stationId:{stationId}}]->(o:Organization) where ID(u)={userId} return o")
    Iterable<Organization> findSynergyOrgByUserIdAndStationId(@Param("userId") Long userId,@Param("stationId")  Long stationId);

    @Query("MATCH(u:User)-[:HAS_ORG{stationId:{stationId}}]->(o:Organization)-[:HAS_CHILD]->(s) where ID(u)={userId} return s")
    Iterable<Organization> findBelongChildOrgByUserId(@Param("userId") Long id,@Param("stationId") Long stationId);

    @Query("MATCH(u:User)-[:HAS_SYNERGY_ORG{stationId:{stationId}}]->(o:Organization)-[:HAS_CHILD]->(s) where ID(u)={userId} return s")
    Iterable<Organization> findSynergyChildOrgByUserId(@Param("userId") Long id,@Param("stationId") Long stationId);
}
